import tornado.websocket
from db import LogsDB
from controllers.baku.baku_controller import BakuController
from controllers.auto_craft.auto_craft_controller import AutoCraftController
from controllers.craft_group.craft_group_controller import CraftGroupController
from controllers.auto_order.auto_order_controller import AutoOrderController
from controllers.auto_salvage_card.auto_salvage_card_controller import AutoSalvageCardController
from controllers.key_press_list.key_press_list_controller import KeyPressListController
from controllers.mouse_click.mouse_click_controller import MouseClickController
from controllers.auto_click_target_image.auto_click_target_image_controller import AutoClickTargetImageController
from controllers.auto_way.auto_way_controller import AutoWayController
from controllers.reset_wow_exe.reset_wow_exe_controller import ResetWowExeController
from controllers.record_events.record_events_controller import RecordEventsController
from controllers.schedule.schedule_controller import ScheduleController
from controllers.record_events.record_player import ActionPlayer
from core.utils import get_image_pos, focus_wow
from core.wow_helper import WowHelper

import os, asyncio, json, time, math, pyautogui
from datetime import datetime

class AppWebSocketHandler(tornado.websocket.WebSocketHandler):
    task_list = []
    clients = set()
    def initialize(self):
        pass
        # print("AppWebSocketHandler initialized", len(self.clients))
        
    def check_origin(self, origin):
        return True
    async def open(self):
        self.clients.add(self)
        self.return_json(type="open")

    async def on_message(self, message):
        # print("Message received: ", message, json.loads(message))
        json_message = {}
        try:
            json_message = json.loads(message)
        except Exception as e:
            pass
        message_type = json_message.get("type", "unknown")
        if message_type == "unknown":
            self.return_json(type="unknown", data=None, message="Unknown message type")

        if message_type == "ping":
            self.return_json(type="pong")
            
        if message_type == "trigger_schedules":
            await self.trigger_schedules()
            
        if message_type == "hot_refresh_schedule":
            self.hot_refresh_schedule(
                extra_data=json_message.get("extra_data", {}),
            )
        if message_type == "toggle_schedule_locked":
            await self.toggle_schedule_locked(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "reset_wow_exe":
            await self.reset_wow_exe(extra_data=json_message.get("extra_data", {}),)
        
        if message_type == "stop_all_task":
            await self.stop_all_task()
        
        if message_type == "start_baku":
            await self.start_baku()
            
        if message_type == "start_craft_group":
            await self.start_craft_group(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "start_auto_craft":
            await self.start_auto_craft(
                extra_data=json_message.get("extra_data", {}),
            )
            
        if message_type == "start_auto_order":
            await self.start_auto_order(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "start_auto_salvage_card":
            await self.start_auto_salvage_card(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "start_key_press_list":
            await self.start_key_press_list(
                extra_data=json_message.get("extra_data", {}),
            )

        if message_type == "start_mouse_click":
            await self.start_mouse_click(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "start_auto_click_target_image":
            await self.start_auto_click_target_image(
                extra_data=json_message.get("extra_data", {}),
            )
        
        if message_type == "start_record_actions":
            if "temp_record_controller" not in self.application.settings["global_temp_vars"]:
                self.application.settings["global_temp_vars"]['temp_record_controller'] = RecordEventsController(task_list=self.task_list, ws_client=self)
            self.application.settings["global_temp_vars"]['temp_record_controller'].start(extra_data=json_message.get("extra_data", {}))
            
        if message_type == "stop_record_actions":
            if "temp_record_controller" not in self.application.settings["global_temp_vars"]:
                self.application.settings["global_temp_vars"]['temp_record_controller'] = RecordEventsController(task_list=self.task_list, ws_client=self)
            self.application.settings["global_temp_vars"]['temp_record_controller'].stop_and_save_to_file()
        
        if message_type == "play_record_actions":
            await self.play_record_actions(extra_data=json_message.get("extra_data", {}))
            
        if message_type == "debug":
            await self.debug()
            # await self.reset_wow_exe()

    async def debug(self):
        # await self.broadcast_log(message_content="debug", message_type=1)
        d_pos = get_image_pos("images_2/server_select.png", confidence=0.8)
        if d_pos:
            print(d_pos.x, d_pos.y)
            im = pyautogui.screenshot(region=(int(d_pos.x), int(d_pos.y+42), 300, 200))

            # 保存截图
            im.save("screenshot666.png")
        print("d_pos", d_pos)
        # pyautogui.click(x=d_pos.x, y=d_pos.y-50)
        # await asyncio.sleep(2)
        # # pyautogui.click(x=d_pos.x - 200, y=d_pos.y-320)
        # pyautogui.click(x=d_pos.x - 200, y=d_pos.y-250)

        # await self.broadcast_log(message_content="debug", message_type=1)
        # await AutoWayController(task_list=self.task_list, ws_client=self).start()
    
    async def trigger_schedules(self):
        if "temp_schedule_controller" not in self.application.settings["global_temp_vars"]:
            self.application.settings["global_temp_vars"]['temp_schedule_controller'] = ScheduleController(task_list=self.task_list, ws_client=self)
        await self.application.settings["global_temp_vars"]['temp_schedule_controller'].trigger()
        
    def hot_refresh_schedule(self, extra_data={}):
        if "temp_schedule_controller" not in self.application.settings["global_temp_vars"]:
            self.application.settings["global_temp_vars"]['temp_schedule_controller'] = ScheduleController(task_list=self.task_list, ws_client=self)
        self.application.settings["global_temp_vars"]['temp_schedule_controller'].hot_refresh_schedule(extra_data=extra_data)

    async def toggle_schedule_locked(self, extra_data={}):
        if "temp_schedule_controller" not in self.application.settings["global_temp_vars"]:
            self.application.settings["global_temp_vars"]['temp_schedule_controller'] = ScheduleController(task_list=self.task_list, ws_client=self)
        await self.application.settings["global_temp_vars"]['temp_schedule_controller'].toggle_schedule_locked(extra_data=extra_data)

    async def reset_wow_exe(self, extra_data={}):
        await ResetWowExeController(task_list=self.task_list, ws_client=self).start(extra_data)
        # await ResetWowExeController(task_list=self.task_list, ws_client=self.ws_client).loop_cmds("wow1")
        
    async def play_record_actions_with_log(self, extra_data):
        events_dir = os.getenv("EVENTS_DIR")
        record_file = os.path.join(events_dir, extra_data.get("record_events_file", "abs_1753415202.json"))
        await ActionPlayer().start(record_file)
        await self.broadcast_log(message_content="play_record_actions end", message_type=1)
    async def play_record_actions(self, extra_data={}):
        await self.broadcast_log(message_content="play_record_actions", message_type=1)
        focus_task = asyncio.create_task(self.play_record_actions_with_log(extra_data))  # 创建任务
        self.task_list.append(focus_task)
    async def start_craft_group(self, extra_data={}):
        await self.broadcast_log(message_content="start_craft_group", message_type=1)
        await CraftGroupController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)
    
    async def start_auto_craft(self, extra_data={}):
        await self.broadcast_log(message_content="start_auto_craft", message_type=1)
        await AutoCraftController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)

    async def start_auto_order(self, extra_data={}):
        await self.broadcast_log(message_content="start_auto_order", message_type=1)
        await AutoOrderController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)

    async def start_auto_salvage_card(self, extra_data={}):
        await self.broadcast_log(message_content="start_auto_salvage_card", message_type=1)
        await AutoSalvageCardController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)

    async def start_key_press_list(self, extra_data={}):
        await self.broadcast_log(message_content="start_key_press_list", message_type=1)
        await KeyPressListController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)
    
    async def start_auto_click_target_image(self, extra_data={}):
        await self.broadcast_log(message_content="start_auto_click_target_image", message_type=1)
        await AutoClickTargetImageController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)
    
    async def start_mouse_click(self, extra_data={}):
        await self.broadcast_log(message_content="start_mouse_click", message_type=1)
        await MouseClickController(task_list=self.task_list, ws_client=self).start(extra_data=extra_data)

    async def start_baku(self):
        await self.broadcast_log(message_content="start_baku", message_type=1)
        await BakuController(task_list=self.task_list, ws_client=self).start()
    async def stop_all_task(self):
        if len(self.task_list):
            for task in self.task_list:
                try:
                    task.cancel()  # 取消任务
                    await task  # 等待任务停止
                except asyncio.CancelledError:
                    pass  # 任务被取消时，不需要处理异常
        self.task_list.clear()  # 清空任务列表
        await self.broadcast_log(message_content="stop_all_task", message_type=1)
    
    async def broadcast_log(self, message_content, message_type=1):
        await LogsDB.create(content=message_content, type=message_type)
        message_data = {
            "content": message_content,
            "type": message_type,
            "created_at": datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        }
        self.broadcast_message(data=message_data, type="log", message="")

    def broadcast_message(self, data, type, message):
        # 广播消息给所有客户端
        for client in self.clients:
            try:
                client.return_json(data, type, message)
            except Exception as e:
                pass
    def return_json(self, data={}, type="success", message=""):
        self.write_message(json.dumps({"type": type, "message": message, "data": data, "time": math.floor(time.time() * 1000)}))

    def on_close(self):
        self.clients.remove(self)